package com.customer.controller.user;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.customer.dto.AIASRDTO;
import com.customer.dto.AITTSDTO;
import com.customer.dto.AITextRequestDTO;
import com.customer.result.Result;
import com.customer.service.AIService;
import com.customer.vo.AIResponseVO;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

@RestController
@RequestMapping("/user/ai")
@Api(tags = "AI对话相关接口")
@Slf4j
public class AIController {

    @Autowired
    private AIService aiService;

    /**
     * AI对话接口
     *
     * @param requestDTO AI文本请求数据
     * @return AI响应结果
     */
    @PostMapping("/chat")
    @ApiOperation("AI对话")
    public Result<AIResponseVO> chat(@RequestBody @Valid AITextRequestDTO requestDTO) {
        log.info("AI对话请求 - userId: {}, sessionId: {}, text: {}",
                requestDTO.getUserId(), requestDTO.getSessionId(), requestDTO.getText());

        // 参数校验
        if (requestDTO.getText() == null || requestDTO.getText().trim().isEmpty()) {
            log.warn("AI对话请求文本为空 - userId: {}", requestDTO.getUserId());
            return Result.error("请求文本不能为空");
        }

        try {
            AIResponseVO responseVO = aiService.callAI(requestDTO);
            log.info("AI对话响应 - userId: {}, sessionId: {}, responseTextLength: {}",
                    requestDTO.getUserId(), responseVO.getSessionId(),
                    responseVO.getText() != null ? responseVO.getText().length() : 0);
            return Result.success(responseVO);
        } catch (Exception e) {
            log.error("AI对话处理异常 - userId: {}, sessionId: {}, error: {}",
                    requestDTO.getUserId(), requestDTO.getSessionId(), e.getMessage(), e);
            return Result.error("AI服务处理失败，请稍后重试");
        }
    }

    /**
     * 文字转语音接口
     *
     * @param aittsdto 文本内容
     * @return 语音数据（Base64编码）
     */
    @PostMapping("/tts")
    @ApiOperation(value = "文字转语音", notes = "将文本转换为语音数据，返回Base64编码的音频内容")
    public Result<String> tts(@RequestBody AITTSDTO aittsdto) {
        log.info("TTS请求 - 文本长度: {}", aittsdto.getText() != null ? aittsdto.getText().length() : 0);

        // 参数校验
        if (aittsdto.getText() == null || aittsdto.getText().trim().isEmpty()) {
            log.warn("TTS请求文本为空");
            return Result.error("请求文本不能为空");
        }

        // 文本长度限制（可根据实际需求调整）
        if (aittsdto.getText().length() > 1000) {
            log.warn("TTS请求文本过长 - 长度: {}", aittsdto.getText().length());
            return Result.error("文本长度超过限制，请输入1000字符以内的文本");
        }

        try {
            // 使用默认音色进行TTS转换
            String audioBase64 = aiService.doTTS(aittsdto.getText(), "qiniu_zh_female_tmjxxy");

            if (audioBase64 == null) {
                log.error("TTS转换失败，返回null");
                return Result.error("语音合成失败");
            }

            log.info("TTS转换成功 - 音频数据长度: {}", audioBase64.length());
            return Result.success(audioBase64);
        } catch (Exception e) {
            log.error("TTS转换异常: {}", e.getMessage(), e);
            return Result.error("语音合成服务异常，请稍后重试");
        }
    }

    /**
     * 语音对话接口（结合ASR和TTS）
     *
     * @param filePath 语音数据
     * @return 语音回复数据（包含文本和语音）
     */
    @PostMapping("/voice-chat")
    @ApiOperation(value = "语音对话", notes = "上传语音，识别文本，获取AI回复，转换为语音返回")
    public Result<Map<String, String>> voiceChat(@RequestParam("filePath") String filePath) {
        try {
            // 1. 语音识别（ASR）
            Long userId = 1L;
            String sessionId = UUID.randomUUID().toString();
            String text = aiService.doASRByFilePath(filePath);
            if (text == null || text.trim().isEmpty()) {
                return Result.error("语音识别失败，请重试");
            }
            // 2. AI对话
            AITextRequestDTO requestDTO = new AITextRequestDTO();
            requestDTO.setUserId(userId);
            requestDTO.setSessionId(sessionId);
            requestDTO.setText(text);
            AIResponseVO aiResponse = aiService.callAI(requestDTO);
            if (aiResponse == null || !aiResponse.getIsCompleted() || aiResponse.getText() == null) {
                return Result.error("AI对话失败，请重试");
            }
            // 3. 文字转语音（TTS）
            String audioBase64 = aiService.doTTS(aiResponse.getText(), "qiniu_zh_female_tmjxxy");
            if (audioBase64 == null) {
                return Result.error("语音合成失败，请重试");
            }

            // 创建返回结果对象，包含文本和语音数据
            Map<String, String> resultData = new HashMap<>();
            resultData.put("text", aiResponse.getText());
            resultData.put("audioBase64", audioBase64);

            return Result.success(resultData);
        } catch (Exception e) {
            log.error("语音对话处理异常: {}", e.getMessage(), e);
            return Result.error("语音对话服务异常，请稍后重试");
        }
    }

    /**
     * 通过文件路径进行语音识别接口
     *
     * @param filePath 音频文件路径
     * @return 转换后的文本结果
     */
    @PostMapping("/asr/file")
    @ApiOperation(value = "通过文件路径进行语音识别", notes = "通过文件路径进行语音识别")
    public Result<String> asrByFilePath(@RequestParam("filePath") String filePath) {
        try {
            if (filePath == null || filePath.isEmpty()) {
                return Result.error("音频文件路径不能为空");
            }

            log.info("接收到文件路径识别请求，路径: {}", filePath);

            // 调用语音识别
            String recognizedText = aiService.doASRByFilePath(filePath);

            if (recognizedText != null) {
                return Result.success(recognizedText);
            } else {
                return Result.error("语音识别失败，未获取到识别结果");
            }
        } catch (FileNotFoundException e) {
            log.error("音频文件不存在: {}", e.getMessage());
            return Result.error("音频文件不存在: " + e.getMessage());
        } catch (Exception e) {
            log.error("ASR文件识别处理异常: {}", e.getMessage(), e);
            return Result.error("语音识别服务异常，请稍后重试: " + e.getMessage());
        }
    }
    /**
     * 保存音频文件接口
     */
    @PostMapping("/save-audio")
    @ApiOperation(value = "保存音频文件", notes = "保存前端录制的音频文件到服务器")
    public Result<String> saveAudioFile(@RequestParam("audioFile") MultipartFile audioFile) {
        try {
            if (audioFile == null || audioFile.isEmpty()) {
                return Result.error("音频文件不能为空");
            }
            // 使用用户指定的绝对路径
            String audioDirPath = "D:\\idea_workspace\\shuo_web_project\\BackOfAI\\src\\main\\resources\\audio\\";
            // 创建audio目录（如果不存在）
            File audioDir = new File(audioDirPath);
            if (!audioDir.exists()) {
                audioDir.mkdirs();
                log.info("创建音频目录: {}", audioDir.getAbsolutePath());
            }

            // 保存文件
            String fileName = audioFile.getOriginalFilename();
            File targetFile = new File(audioDir.getAbsolutePath() + File.separator + fileName);
            audioFile.transferTo(targetFile);

            log.info("音频文件保存成功，路径: {}, 大小: {}字节",
                    targetFile.getAbsolutePath(), targetFile.length());

            // 返回文件的绝对路径给前端
            return Result.success(targetFile.getAbsolutePath());
        } catch (Exception e) {
            log.error("保存音频文件异常: {}", e.getMessage(), e);
            return Result.error("保存音频文件失败，请稍后重试");
        }
    }

    /**
     * 语音转文字接口
     *
     * @param audioData  音频文件
     * @param format     音频格式
     * @param sampleRate 采样率
     * @return 转换后的文本结果
     */
    /**
     * 语音识别接口
     */
    @PostMapping("/asr")
    @ApiOperation(value = "语音转文字", notes = "语音接口")
    public Result<String> asr(
            @RequestParam("audioData") MultipartFile audioFile,
            @RequestParam(value = "format", defaultValue = "pcm") String format,
            @RequestParam(value = "sampleRate", defaultValue = "16000") Integer sampleRate) {

        try {
            if (audioFile == null || audioFile.isEmpty()) {
                return Result.error("音频文件不能为空");
            }

            // 读取音频文件数据
            byte[] audioBytes = audioFile.getBytes();

            // 调用语音识别
            String recognizedText = aiService.doASRByData(audioBytes, format, sampleRate);

            if (recognizedText != null) {
                return Result.success(recognizedText);
            } else {
                return Result.error("语音识别失败");
            }
        } catch (Exception e) {
            log.error("ASR处理异常: {}", e.getMessage(), e);
            return Result.error("语音识别服务异常，请稍后重试");
        }
    }

    @PostMapping("/asr/url")
    @ApiOperation(value = "语音转文字(URL方式)", notes = "通过URL将音频转换为文本")
    public Result<String> asrByUrl(@RequestBody AIASRDTO aiasrdto) {
        log.info("ASR请求 - URL: {}, 格式: {}",
                aiasrdto.getAudioUrl(),
                aiasrdto.getFormat());

        // 参数校验 - 只检查audioUrl
        if (aiasrdto.getAudioUrl() == null || aiasrdto.getAudioUrl().trim().isEmpty()) {
            log.warn("ASR请求音频URL为空");
            return Result.error("请提供音频URL");
        }

        try {
            // 仅使用URL方式处理
            String text = aiService.doASRByUrl(aiasrdto.getAudioUrl(), aiasrdto.getFormat(), aiasrdto.getSampleRate());

            if (text == null) {
                log.error("ASR转换失败，返回null");
                return Result.error("语音识别失败");
            }

            log.info("ASR转换成功 - 识别文本长度: {}", text.length());
            return Result.success(text);
        } catch (Exception e) {
            log.error("ASR转换异常: {}", e.getMessage(), e);
            return Result.error("语音识别服务异常，请稍后重试");
        }
    }
}
